package jpf.nextsearch.ds.dao.base;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import jpf.nextsearch.base.GenericObjectInterface;
import jpf.nextsearch.base.GlobalConfiguration;
import jpf.nextsearch.exception.InitializationException;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * @author <a href="mailto:jacek.pruszkowski@gmail.com">Jacek Pruszkowski</a>
 * 
 */
public abstract class AbstractDaoHibernate<T extends Object> extends
		HibernateDaoSupport implements Dao<T>, GenericObjectInterface {

	private boolean loggingDebug;
	private boolean loggingError;
	private boolean loggingWarning;
	private boolean loggingInfo;
	private GlobalConfiguration globalConfiguration;
	private Logger logger;
	protected Class<T> clazz;

	protected AbstractDaoHibernate(Class<T> clazz) {
		this.clazz = clazz;
		setLogger(Logger.getLogger(this.getClass()));		
	}

	public T get(Serializable id) {
		return (T) getHibernateTemplate().get(clazz, id);
	}

	@SuppressWarnings("unchecked")
	public List<T> getAll() {
		return (List<T>) getHibernateTemplate().find("from " + clazz.getName());
	}

	public void remove(Serializable id) {
		Object obj = getHibernateTemplate().load(clazz, id);
		getHibernateTemplate().delete(obj);
	}

	public void removeAll() {
		getHibernateTemplate().deleteAll(getAll());
	}

	public void saveOrUpdate(T obj) {
		getHibernateTemplate().saveOrUpdate(obj);
	}
	
	public void saveOrUpdateAll(Collection<T> items) {
		getHibernateTemplate().saveOrUpdateAll(items);
	}	

	public int executeUpdateQuery(String query) {
		Query q = getSession().createQuery(query);
		return q.executeUpdate();
	}

	@SuppressWarnings("unchecked")
	public List<? extends Object> executeQuery(String query) {
		return getHibernateTemplate().find(query);
	}

	@SuppressWarnings("unchecked")
	public List<? extends Object> executeSqlQuery(String queryString) {
		Query query = getSession().createSQLQuery(queryString);
		return query.list();
	}
	
	/**
	 * @return the loggingDebug
	 */
	public boolean isLoggingDebug() {
		return loggingDebug;
	}
	
	/**
	 * @param loggingDebug
	 *            the loggingDebug to set
	 */
	public void setLoggingDebug(boolean loggingDebug) {
		this.loggingDebug = loggingDebug;
	}
	
	/**
	 * @return the loggingError
	 */
	public boolean isLoggingError() {
		return loggingError;
	}
	
	/**
	 * @param loggingError
	 *            the loggingError to set
	 */
	public void setLoggingError(boolean loggingError) {
		this.loggingError = loggingError;
	}
	
	/**
	 * @return the loggingWarning
	 */
	public boolean isLoggingWarning() {
		return loggingWarning;
	}
	
	/**
	 * @param loggingWarning
	 *            the loggingWarning to set
	 */
	public void setLoggingWarning(boolean loggingWarning) {
		this.loggingWarning = loggingWarning;
	}
	
	/**
	 * @return the loggingInfo
	 */
	public boolean isLoggingInfo() {
		return loggingInfo;
	}
	
	/**
	 * @param loggingInfo
	 *            the loggingInfo to set
	 */
	public void setLoggingInfo(boolean loggingInfo) {
		this.loggingInfo = loggingInfo;
	}
	
	/**
	 * @return the globalConfiguration
	 */
	public GlobalConfiguration getGlobalConfiguration() {
		return globalConfiguration;
	}
	
	/**
	 * @param globalConfiguration
	 *            the globalConfiguration to set
	 */
	public void setGlobalConfiguration(GlobalConfiguration globalConfiguration) {
		this.globalConfiguration = globalConfiguration;
	}
	
	/**
	 * Get the value of logger
	 * 
	 * @return the value of logger
	 */
	public Logger getLogger() {
		return logger;
	}
	
	/**
	 * Set the value of logger
	 * 
	 * @param logger
	 *            new value of logger
	 */
	public void setLogger(Logger logger) {
		this.logger = logger;
	}
	
	public void init() throws InitializationException {
		if (isLoggingInfo()) {
			getLogger().info(
				"Initialising " + getClass().getName() + " object instance");
		}
	}
	
	public void destroy() {
		if (isLoggingInfo()) {
			getLogger().info(
				"Destroying " + getClass().getName() + " object instance");
		}
	}
	

}
